package models;

import java.util.LinkedList;
import java.util.List;

import javax.persistence.*;

import play.data.validation.Required;
import play.db.jpa.Model;

/**
 * Class description
 * 
 * @author Ibrahim Kessba
 * @version 2011.0424
 * @category C2 Modles
 * @return None Number of Relations: 9
 */


@Entity
public class Eentity extends Model {

	@OneToMany (mappedBy = "relatedEntity", cascade=CascadeType.ALL)
	public List<Role> roles;
	@Required
	private String name;
	@Required
	@OneToMany (mappedBy = "entity",  cascade=CascadeType.ALL)
	private List<Topic> topics;
	@Required
	private String description;
	// Relationship #1 Join between Entity And User_IK
	@Required
	@ManyToMany
	private List<User> members;		
	@Required
	@ManyToOne
	private Organization organization;
	// // Relationship #6 BelongsTo between Entity And Tag_IK
	@Required
	@ManyToMany (mappedBy = "taggedEntity", cascade=CascadeType.ALL)
	private List<Tag> tags;
	// Relationship #7 BelongsTo between Entity And Idea_IK
	@Required
	@OneToMany (mappedBy = "entity", cascade=CascadeType.ALL)
	private List<Idea> ideas;
	@Required
	private LinkedList<Eentity> relatedEntities;// list of the related

	// entities to the
	@Required
	@OneToMany (mappedBy = "assignedEntity",  cascade=CascadeType.ALL)
	private List <Invitation> invitations;
	
	@Required
	@OneToMany (mappedBy = "entity",  cascade=CascadeType.ALL)
	private List <Item> relatedItems;

	public Eentity() {

		members = new LinkedList<User>();
		ideas = new LinkedList<Idea>();
		tags = new LinkedList<Tag>();
		topics = new LinkedList<Topic>();
		relatedEntities = new LinkedList<Eentity>();
		invitations = new LinkedList <Invitation>();

	}

	/**
	 * Entity constructor (that takes only the name and description)
	 * 
	 * @author Ebtehal Abed
	 * @version 2011.04.25
	 * @category C2S1
	 * @params String name, String discription
	 * @return nothing
	 */

	public Eentity(String name, String discription) {

		this();
		this.name = name;
		this.description = discription;
	
	}

	public Eentity(User owner, String name, String discription) {

		this();
		
		this.name = name;
		this.description = discription;
        Role role = new Role(this,"Creator");
		//owner.getRoleList().add(new Role(this, "Creator"),owner);
		addMember(owner);

	}

	/**
	 * Returns a list of all organizers in the entity
	 * 
	 * @author Hossam Saraya
	 * @version 2011.0424
	 * @category C1S10
	 * @return LinkedList<User>: list of all organizers
	 */
	/*public LinkedList<User> getAllOrganizers() {
		return (LinkedList<User>) organizers;
	}*/

	/**
	 * get all users in entity
	 * 
	 * @author Mohamed Shalaby
	 * @version 2011.04.24
	 * @category C2 D6
	 * @param no
	 *            parameters needed
	 * @return List : list of all the users in the entity
	 */

	public LinkedList<User> getAllUsersInEntity() {
		return this.getMembers();
	}

	public void setTopics(LinkedList<Topic> topics) {
		this.topics = topics;
	}

	public List<Topic> getTopics() {
		return  topics;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDiscription() {
		return description;
	}

	public void setDiscription(String discription) {
		this.description = discription;
	}
	

	public LinkedList<User> getOrganizers() {
		LinkedList<User> organisers  = new LinkedList<User>();
		
		
		for (int i=0;i<members.size();i++)
		{
			for(int j = 0; j< members.get(i).getRoleList().size(); j++) {
				if (members.get(i).getRoleList().get(j).getTitle().equalsIgnoreCase("Organizer") &&
						(members.get(i).getRoleList().get(j).getRelatedEntity() != null)
					&&	members.get(i).getRoleList().get(j).getRelatedEntity().equals(this)) {
					organisers.add(members.get(i));
				}
			}
			
		}
		return organisers;
	}

	public LinkedList<User> getFollowers() {
		LinkedList<User> followers  = new LinkedList<User>();
		
		
		for (int i=0;i<members.size();i++)
		{
			for(int j = 0; j< members.get(i).getRoleList().size(); j++) {
				if (members.get(i).getRoleList().get(j).getTitle().equalsIgnoreCase("Follower") &&
						(members.get(i).getRoleList().get(j).getRelatedEntity() != null)
					&&	members.get(i).getRoleList().get(j).getRelatedEntity().equals(this)) {
					followers.add(members.get(i));
				}
			}
			
		}
		return followers;
	}

	public LinkedList<User> getMembers() {
		LinkedList<User> members  = new LinkedList<User>();
		
		
		for (int i=0;i<members.size();i++)
		{
			for(int j = 0; j< members.get(i).getRoleList().size(); j++) {
				if (members.get(i).getRoleList().get(j).getTitle().equalsIgnoreCase("Member") &&
						(members.get(i).getRoleList().get(j).getRelatedEntity() != null)
					&&	members.get(i).getRoleList().get(j).getRelatedEntity().equals(this)) {
					members.add(members.get(i));
				}
			}
			
		}
		return members;
	}
	public User getOwner() {
		for (int i=0;i<members.size();i++)
		{
			for(int j = 0; j< members.get(i).getRoleList().size(); j++) {
				if (members.get(i).getRoleList().get(j).getTitle().equalsIgnoreCase("Creator") &&
						(members.get(i).getRoleList().get(j).getRelatedEntity() != null)
					&&	members.get(i).getRoleList().get(j).getRelatedEntity().equals(this)) {
				return members.get(i);
				}
			}
			
		}
		return null;
	}

	public void addOrganizer(User organizer) {
		
		new Role(this,"Organizer");
		members.add(organizer);
		organizer.addEntity(this);
	}
	
	public void setFollowers(User follower) {
	   new Role(this,"Follower");
		members.add(follower);
	}
	
	public void setMembers (User member){
		new Role (this,"Member");
		members.add(member);
	}
	
	public void setOwner (User owner){
		new Role (this,"Creator");
		members.add(owner);
		owner.addEntity(this);
	}

	public Organization getOrganization() {
		return organization;
	}
	public void setOrganization(Organization organization) {
		if(this.organization != null) {
		if(this.organization.id != organization.id) {
			this.organization = organization;
			organization.addEntity(this);
		}
		} else {
			this.organization = organization;
			organization.addEntity(this);
		}
	}
	public LinkedList<Tag> getTags() {
		return (LinkedList<Tag>) tags;
	}

	public void setTags(LinkedList<Tag> tags) {
		this.tags = tags;
	}

	public List<Idea> getIdeas() {
		return  ideas;
	}

	public void setIdeas(LinkedList<Idea> ideas) {
		this.ideas = ideas;
	}

	public void setMembers(LinkedList<User> members) {
		this.members = members;
	}

	public void setRelatedEntities(LinkedList<Eentity> relatedEntities) {
		this.relatedEntities = relatedEntities;
	}

	public LinkedList<Eentity> getRelatedEntities() {
		return (LinkedList<Eentity>) relatedEntities;
	}

	public void setInvitations(List <Invitation> invitations) {
		this.invitations = invitations;
	}

	public List <Invitation> getInvitations() {
		return invitations;
	}

	public void setRelatedItems(LinkedList <Item> relatedItems) {
		this.relatedItems = relatedItems;
	}

	public List <Item> getRelatedItems() {
		return relatedItems;
	}
	public List<User> getAllUsers(){
		return members;
	}

	public void addTopic(Topic topic) {
		if(!has(topic)) {
			topics.add(topic);
			topic.setEntity(this);
		}
	}

	private boolean has(Topic topic) {
		for(int i = 0;i < topics.size();i++)
			if(topics.get(i).id == topic.id)
				return true;
		return false;
	}

	public void addTag(Tag tag) {
		if(!has(tag)) {
			tags.add(tag);
			tag.addEntity(this);
		}
	}

	private boolean has(Tag tag) {
		for(int i = 0;i < tags.size();i++)
			if(tags.get(i).id == tag.id)
				return true;
		return false;
	}

	public void addIdea(Idea idea) {
		if(!has(idea)) {
			ideas.add(idea);
			idea.setEntity(this);
		}
	}

	private boolean has(Idea idea) {
		for(int i = 0;i < ideas.size();i++)
			if(ideas.get(i).id == idea.id)
				return true;
		return false;
	}

	public void addFollower(User user) {
		if(!has(user)) {
			Role role = new Role(this, "Follower");
			user.addRole(role);
			members.add(user);
			user.addEntity(this);
		}
	}

	private boolean has(User user) {
		for(int i = 0;i < members.size();i++)
			if(members.get(i).id == user.id)
				return true;
		return false;
	}

	public void addMember(User user) {
		if(!has(user)) {
			Role role = new Role(this, "Member");
			user.addRole(role);
			members.add(user);
			user.addEntity(this);
		}
	}

}
